using System;
using System.Collections;
using System.Diagnostics;
using System.Text;
using ActiproSoftware.SyntaxEditor.Addons.Simple.Ast;

namespace ActiproSoftware.SyntaxEditor.Addons.Simple.Ast {

	/// <summary>
	/// Represents a function access expression.
	/// </summary>
	public class FunctionAccessExpression : ActiproSoftware.SyntaxEditor.Addons.Simple.Ast.Expression {

		/// <summary>
		/// Gets the context ID for the function name.
		/// </summary>
		public const byte FunctionNameContextID = ActiproSoftware.SyntaxEditor.Addons.Simple.Ast.Expression.ExpressionContextIDBase;

		/// <summary>
		/// Gets the context ID for the collection of expression parameters.
		/// </summary>
		public const byte ParameterContextID = ActiproSoftware.SyntaxEditor.Addons.Simple.Ast.Expression.ExpressionContextIDBase + 1;

		/// <summary>
		/// Gets the minimum context ID that should be used in your code for AST nodes inheriting this class.
		/// </summary>
		/// <remarks>
		/// Base all your context ID constants off of this value.
		/// </remarks>
		protected const byte FunctionAccessExpressionContextIDBase = ActiproSoftware.SyntaxEditor.Addons.Simple.Ast.Expression.ExpressionContextIDBase + 2;

		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// OBJECT
		/////////////////////////////////////////////////////////////////////////////////////////////////////

		/// <summary>
		/// Initializes a new instance of the <c>FunctionAccessExpression</c> class.
		/// </summary>
		/// <param name="functionName">The function name.</param>
		public FunctionAccessExpression(Identifier functionName) {
			// Initialize parameters
			this.FunctionName = functionName;
		}

		/// <summary>
		/// Initializes a new instance of the <c>FunctionAccessExpression</c> class. 
		/// </summary>
		public FunctionAccessExpression() {}

		/// <summary>
		/// Initializes a new instance of the <c>FunctionAccessExpression</c> class. 
		/// </summary>
		/// <param name="textRange">The <see cref="TextRange"/> of the AST node.</param>
		public FunctionAccessExpression(TextRange textRange) : base(textRange) {}

		/////////////////////////////////////////////////////////////////////////////////////////////////////
		// PUBLIC PROCEDURES
		/////////////////////////////////////////////////////////////////////////////////////////////////////

		/// <summary>
		/// Accepts the specified visitor for visiting this node.
		/// </summary>
		/// <param name="visitor">The visitor to accept.</param>
		/// <remarks>This method is part of the visitor design pattern implementation.</remarks>
		protected override void AcceptCore(AstVisitor visitor) {
			if (visitor.OnVisiting(this)) {
				// Visit children
				if (this.ChildNodeCount > 0)
					this.AcceptChildren(visitor, this.ChildNodes);
			}
			visitor.OnVisited(this);
		}
		
		/// <summary>
		/// Gets the <see cref="SimpleNodeType"/> that identifies the type of node.
		/// </summary>
		/// <value>The <see cref="SimpleNodeType"/> that identifies the type of node.</value>
		public override SimpleNodeType NodeType { 
			get {
				return SimpleNodeType.FunctionAccessExpression;
			}
		}

		/// <summary>
		/// Gets or sets the function name.
		/// </summary>
		/// <value>The function name.</value>
		public Identifier FunctionName {
			get {
				return this.GetChildNode(FunctionAccessExpression.FunctionNameContextID) as Identifier;
			}
			set {
				this.ChildNodes.Replace(value, FunctionAccessExpression.FunctionNameContextID);
			}
		}

		/// <summary>
		/// Gets the collection of expression parameters.
		/// </summary>
		/// <value>The collection of statements.</value>
		public IAstNodeList Parameters {
			get {
				return new AstNodeListWrapper(this, FunctionAccessExpression.ParameterContextID);
			}
		}

		/// <summary>
		/// Gets text representing the node that can be used for display, such as in a document outline.
		/// </summary>
		/// <value>Text representing the node that can be used for display, such as in a document outline.</value>
		public override string DisplayText {
			get {
				return "Call to Function " + this.FunctionName.Text;
			}
		}

	}

}
